package frame.options.virtual;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.List;
import java.util.Locale;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import model.components.links.link.VirtualLink;
import model.components.networks.virtual.VirtualNetwork;
import model.components.nodes.node.virtual.VirtualNode;
import frame.SimulatorFrame;

@SuppressWarnings("serial")
public class SaveVirtualMenuItem extends JMenuItem implements ActionListener
{
	private SimulatorFrame simulatorFrame;
	public SimulatorFrame getFrame(){ return simulatorFrame; }
	public void setFrame( SimulatorFrame simulatorFrame ){ this.simulatorFrame = simulatorFrame; }

	private JFileChooser fileChooser;
	public JFileChooser getFileChooser(){ return fileChooser; }
    public void setFileChooser( JFileChooser fileChooser ){ this.fileChooser = fileChooser; }
	
	public SaveVirtualMenuItem( SimulatorFrame simulatorFrame )
	{
		this.setFrame( simulatorFrame );
		
		this.setText( "Save" );
		this.setMnemonic( KeyEvent.VK_S );
		this.setIcon( new ImageIcon( this.getClass().getResource( "/icons/save.png" ) ) );
		this.setFileChooser( new JFileChooser() );
		this.addActionListener( this );
		
		if( this.getFrame().getSimulator().getVirtualNetworks().size() == 0 )
			this.setEnabled( false );
		else
			this.setEnabled( true );
	}
	
	@Override
	public void actionPerformed( ActionEvent actionEvent )
	{
		this.getFrame().getNetworksPanel().getNetworksTablesTabbedPane().setSelectedIndex( 1 );
		this.getFileChooser().setSelectedFile( new File( this.getFrame().getSimulator().getVirtualNetworks().get( 0 ).getNamePrefix() + "s" ) );
		
		if( this.getFileChooser().showSaveDialog( this ) == JFileChooser.APPROVE_OPTION )
		{
			try
			{
				if( !this.existFile( new File( this.getFileChooser().getSelectedFile().toString()+ ".xls" ) ) )
					this.saveVirtualNetworks( this.getFrame().getSimulator().getVirtualNetworks(), this.getFileChooser().getSelectedFile().toString() );
				else
					throw new Exception();
			}
			catch( Exception exception )
			{
				JOptionPane.showMessageDialog( this.getFrame().getNetworksPanel(), "Already exists file", "File name error", 1 );
			}
		}
	}
	
	private boolean existFile( File file )
	{
		try
		{
			Workbook workbook = Workbook.getWorkbook( file );
			workbook.close();
			return true;
		}
		catch( Exception exception )
		{
			return false;
		}
	}
	
	private void saveVirtualNetworks( List< VirtualNetwork > virtualNetworks, String file ) throws Exception
	{	
		WorkbookSettings workbookSettings = new WorkbookSettings();
		workbookSettings.setLocale( new Locale( "en", "EN" ) );
		WritableWorkbook writableWorkbook = Workbook.createWorkbook( new File( file + ".xls" ), workbookSettings );
		
		WritableFont writableFontBold = new WritableFont( WritableFont.ARIAL, 10, WritableFont.BOLD );
		WritableCellFormat writableCellFormatBold = new WritableCellFormat( writableFontBold );
		writableCellFormatBold.setWrap( true );
							
		WritableFont writableFontNoBold = new WritableFont( WritableFont.ARIAL, 10, WritableFont.NO_BOLD );
		WritableCellFormat writableCellFormatNoBold = new WritableCellFormat( writableFontNoBold );
		writableCellFormatNoBold.setWrap( true );
		
		int sheetIndex = 0;
		
		for( VirtualNetwork virtualNetwork: virtualNetworks )
		{
			WritableSheet writableSheet = writableWorkbook.createSheet( virtualNetwork.getName(), sheetIndex++ );
			
			int rowCount = 0;
			
			int columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "NETWORK", writableCellFormatBold ) );
			rowCount++;
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "Name prefix", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Number", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Starting date", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Ending date", writableCellFormatBold ) );
			rowCount++;
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, virtualNetwork.getNamePrefix(), writableCellFormatNoBold ) );
			writableSheet.addCell( new Number( columnCount++, rowCount, virtualNetwork.getNumber(), writableCellFormatNoBold ) );
			writableSheet.addCell( new Number( columnCount++, rowCount, virtualNetwork.getStartingDate(), writableCellFormatNoBold ) );
			writableSheet.addCell( new Number( columnCount++, rowCount, virtualNetwork.getEndingDate(), writableCellFormatNoBold ) );
			rowCount++;
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "NODES", writableCellFormatBold ) );
			rowCount++;
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "Network name", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Number", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Type", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "OS", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "CPU", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "RAM", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Storage", writableCellFormatBold ) );
			rowCount++;
			
			for( VirtualNode virtualNode: virtualNetwork.getVirtualNodes() )
			{
				columnCount = 0;
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualNode.getNetworkName(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualNode.getNumber(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualNode.getType(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualNode.getOS(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualNode.getCPU(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualNode.getRAM(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualNode.getStorage(), writableCellFormatNoBold ) );
				rowCount++;
			}
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "LINKS", writableCellFormatBold ) );
			rowCount++;
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "Network name", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Number", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "First node", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "Second node", writableCellFormatBold ) );
			writableSheet.addCell( new Label( columnCount++, rowCount, "BW", writableCellFormatBold ) );
			rowCount++;
			
			for( VirtualLink virtualLink: virtualNetwork.getVirtualLinks() )
			{
				columnCount = 0;
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualLink.getNetworkName(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualLink.getNumber(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualLink.getFirstNode().getName(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Label( columnCount++, rowCount, virtualLink.getSecondNode().getName(), writableCellFormatNoBold ) );
				writableSheet.addCell( new Number( columnCount++, rowCount, virtualLink.getBW(), writableCellFormatNoBold ) );
				rowCount++;
			}
			
			columnCount = 0;
			writableSheet.addCell( new Label( columnCount++, rowCount, "END", writableCellFormatBold ) );
			rowCount++;
		}
		
		writableWorkbook.write();
		writableWorkbook.close();
		
	}

}
